package Main;

import java.util.ArrayList;

public class TheaterEvent 
{
	public enum State
	{
	 Open,
	 Closed
	};
	private static long lastId = 0;
	public long id;
	public String Title;
	public String Date;
	public String Time;
	public int HallId;
	//public int MaxCapacity;
	public State BookingState;
	private Booking[] Bookings;
	private int NumBookings;
	//TheaterEvents are not created in a multithreaded environment, but, to be safe from future modifications, it is protected
	public synchronized long NextId()
	{
		return ++lastId;
	}
	public TheaterEvent(String title, String date, String time, int hallId, int capacity)
	{
		id=NextId();
		Title=new String(title);
		Date=new String(date);
		Time=new String(time);
		//MaxCapacity=capacity;
		HallId=hallId;
		Bookings=new Booking[capacity];
		NumBookings=0;
		BookingState=State.Open;
	}
	public void AddBooking(String first, String last) throws TheaterException
	{
		AddBooking(first, last, 0);
	}
	public synchronized void AddBooking(String first, String last, int number) throws TheaterException
	{
		if(BookingState==State.Closed)
			throw new TheaterException("TheaterEvent: This event is fully booked.");
		//if number is 0, then get the first available seat
		if(number==0)
		{
			for(int i=0;i<Bookings.length;i++)
				if(Bookings[i]==null)
				{
					Bookings[i]=new Booking(this, first, last, i+1);
					NumBookings++;
					break;
				}
		}
		//if the number is a valid seat then attempt to get it
		else if(number>0 && number<=Bookings.length)
		{
			int id=number-1;
			if(Bookings[id]==null)
			{
				Bookings[id]=new Booking(this, first, last, number);
				NumBookings++;
			}
			else throw new TheaterException("TheaterEvent: Requested seat is already taken.");
		}
		else throw new TheaterException("TheaterEvent: Requested seat does not exist.");
		
		if(NumBookings>=Bookings.length)
			BookingState=State.Closed;
	}
	public boolean IsPlaceFree(int number)
	{
		return number>0
				&&number<=Bookings.length
				&&Bookings[number]==null;
	}
	public void AssertPlacesAreFree(ArrayList<Integer> numbers) throws TheaterException
	{
		
		if(numbers.size()+NumBookings>Bookings.length)
			throw new TheaterException(this+"Error: There are not enough seats left.");
		String err=new String();
		for(Integer n : numbers)
			if(n!=0&&!IsPlaceFree(n))
				err+=n+" ";
		if(!err.isEmpty())
			throw new TheaterException(this+"Error: Seats "+err+"are not available.");
	}
	public ArrayList<Booking> GetAllBookings()
	{
		ArrayList<Booking> bookings=new ArrayList<Booking>();
		for(int i=0;i<Bookings.length;i++)
			if(Bookings[i]!=null)
				bookings.add(Bookings[i]);
		return bookings;
	}
	public String toString()
	{
		String str=new String();
		str+="ID: "+id+"\n";
		str+="Title: "+Title+"\n";
		str+="Date: "+Date+" "+Time+"\n";
		str+="Hall: "+HallId+" Capacity: "+Bookings.length+"\n";
		return str;
	}
}
